package com.transaction.simulate.service.impl;

import com.transaction.common.util.DateUtil;
import com.transaction.simulate.mapper.FundMapper;
import com.transaction.simulate.mapper.IndexMapper;
import com.transaction.simulate.model.dto.Fund;
import com.transaction.simulate.model.dto.FundYield;
import com.transaction.simulate.model.vo.FundVo;
import com.transaction.simulate.model.vo.FundYieldVo;
import com.transaction.simulate.service.FundService;
import com.transaction.simulate.service.IndexService;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
public class FundServiceImpl implements FundService {

    private static Logger LOGGER = LoggerFactory.getLogger(FundServiceImpl.class);

    @Autowired
    private FundMapper fundMapper;

    @Autowired
    private IndexService indexService;

    @Autowired
    private IndexMapper indexMapper;

    @Override
    public List<FundVo> getFundList(String channelCode,String fundCode) {
        return fundMapper.getFundList(channelCode,fundCode);
    }

    @Override
    public Map<String, Object> getViewFundData(Map<String,Object> map) {

        String channelCode = MapUtils.getString(map,"channelCode");
        String fundCode = MapUtils.getString(map,"fundCode");
        String month = MapUtils.getString(map,"month");

        if(Objects.isNull(month)){
            month = "1";
        }

        FundVo fundVo = fundMapper.getFundList(channelCode,fundCode).get(0);
        String fundType = fundVo.getFundType();

        Map<String,Object> retMap = new HashMap<>();
        FundYieldVo fundYieldVo = new FundYieldVo(channelCode,fundCode,fundType,month);
        //1、查询横坐标时间
        List<String> transDateList = indexMapper.selectFundYieldTransDate(fundYieldVo);
        //2、查询纵坐标内容
        List<FundYieldVo> fundYieldVoList = indexMapper.selectFundYieldVoList(fundYieldVo);

        if(CollectionUtils.isEmpty(fundYieldVoList)){
            retMap.put("transDateList",new ArrayList<String>());
            retMap.put("dataList",new ArrayList<BigDecimal>());
            return retMap;
        }

        FundYieldVo fundYield = fundYieldVoList.get(0);
        List<String> fundIncomeList = Arrays.asList(fundYield.getFundIncomes().split(","));
        List<String> dateList = Arrays.asList(fundYield.getTransDates().split(","));

        Map<String,String> transIncomeMap = indexService.buildDateToFundIncome(dateList,fundIncomeList);
        List<BigDecimal> data = new ArrayList<>();
        transDateList.forEach(transDate ->{
            data.add(new BigDecimal(MapUtils.getString(transIncomeMap,transDate,"0")));
        });

        retMap.put("transDateList",transDateList);
        retMap.put("dataList",data);
        retMap.put("fundVo",fundVo);
        return retMap;
    }

    @Override
    public FundVo getFundVo(Map<String, Object> map) {
        String channelCode = MapUtils.getString(map,"channelCode");
        String fundCode = MapUtils.getString(map,"fundCode");
        FundVo fundVo = fundMapper.getFundList(channelCode,fundCode).get(0);
        return fundVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.SUPPORTS)
    public void insertFundInfo(String channelCode, String transDate, List<Map<String, Object>> dataList) {
        dataList.forEach(v->{
            if(StringUtils.equals("0", MapUtils.getString(v,"FUNDINCOME"))){
                //净值型
                v.put("FUNDTYPE","1");
            }else{
                //非净值型
                v.put("FUNDTYPE","2");
            }
            fundMapper.insertOrUpdateFund(channelCode,v);
        });
        LOGGER.info("插入产品净值或七日年化表");
        fundMapper.deleteFundYieldByChannelAndTransDate(channelCode,transDate);
        fundMapper.insertFundYield(channelCode,transDate,dataList);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void deleteFund(Fund fund) {
        fundMapper.deleteFund(fund);
        fundMapper.deleteFundYield(fund);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void addFund(Fund fund) {

        List<FundVo> fundList = fundMapper.getFundList(fund.getChannelCode(),fund.getFundCode());
        if(CollectionUtils.isEmpty(fundList)){
            fundMapper.insertFund(fund);
        }

        FundYield fundYield = new FundYield(fund.getChannelCode(),
                fund.getFundCode(),
                "0",
                DateUtil.formatDate(new Date(),DateUtil.FORMAT_STR_TIME8),
                DateUtil.formatDate(new Date(),DateUtil.FORMAT_STR_TIME8));
        fundMapper.insertFundYieldInit(fundYield);
    }
}
